<?php

namespace fakis\aceeditor;

use yii\helpers\Html;
use yii\helpers\Inflector;
use yii\helpers\Json;
use yii\widgets\InputWidget;

/**
 * 代码编辑器
 * Class AceEditor
 * @package fakis\aceeditor
 *
 * @author Fakis <fakis738@qq.com>
 */
class AceEditor extends InputWidget
{
    /**
     * 是否只读
     * @var boolean
     */
    public $readOnly = false;

    /**
     * 代码语言模式
     * @var string
     */
    public $mode = 'html';

    /**
     * 主题
     * @var string
     * @link https://github.com/ajaxorg/ace/tree/master/lib/ace/theme
     */
    public $theme = 'monokai';

    /**
     * 字体大小
     * @var int
     */
    public $fontSize = 14;

    /**
     * 编辑器选项
     * @var bool
     */
    public $editorOptions = [];

    /**
     * 容器选项
     * @var array
     */
    public $containerOptions = [
        'style' => 'width: 100%; min-height: 400px;'
    ];

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();

        AceEditorAsset::register($this->getView());

        $id = $this->getId();
        $aceEditor = 'AceEditor_' . Inflector::id2camel($id);
        $aceEditorTextarea = 'AceEditorTextarea_' . Inflector::id2camel($id);

        // 加载控件所需的js
        $js = <<<JS
  var {$aceEditor} = ace.edit("{$id}");
  var {$aceEditorTextarea} = $("#{$this->options['id']}");
  {$aceEditor}.setTheme("ace/theme/{$this->theme}");
  {$aceEditor}.setFontSize({$this->fontSize});
  {$aceEditor}.getSession().setMode("ace/mode/{$this->mode}");
  {$aceEditor}.getSession().setValue({$aceEditorTextarea}.val());
JS;
        $this->getView()->registerJs($js);

        // 是否只读
        if ($this->readOnly) {
            $js = <<<JS
  {$aceEditor}.setReadOnly(true);
JS;
        } else {
            $js = <<<JS
  {$aceEditor}.getSession().on("change", function() {
    {$aceEditorTextarea}.val({$aceEditor}.getSession().getValue());
  });
JS;
        }
        $this->getView()->registerJs($js);

        // 设置编辑器选项
        if (!empty($this->editorOptions)) {
            $editorOptions = Json::encode($this->editorOptions);
            $this->getView()->registerJs("{$aceEditor}.setOptions({$editorOptions})");
        }

        // 加载控件所需的css
        Html::addCssStyle($this->options, 'display: none;');
        $this->containerOptions['id'] = $id;
    }

    /**
     * @inheritdoc
     */
    public function run()
    {
        $content = Html::tag('div', $this->value, $this->containerOptions);
        if ($this->hasModel()) {
            $content .= Html::activeTextarea($this->model, $this->attribute, $this->options);
        } else {
            $content .= Html::textarea($this->name, $this->value, $this->options);
        }
        return $content;
    }
}
